<?php
/**
 * @name /www/donations/controller.php
 * @author Michael Foss <michael@mikefoss.com>
 * @version 2011.03.31
 *
 * Server-side functionality for handling ajax & form posts.
 */

// Sets up configuration settings and includes libraries.
require_once('_ini.php');
ReqLib('/lib/private/User.php');
ReqLib('/lib/private/Donation.php');
ReqLib('/lib/private/DonatedItem.php');
ReqLib('/lib/private/ItemSearchWidget.php');

function DoController($action, &$user) {
  if (strlen($action) >= 5 && substr($action, 0, 5) == "Ajax_") {
    $action = substr($action, 5);
    header('content-type: application/json');
    DoAjax($action, $user);
  }
  else {
    DoPost($action, $user);
    header('location: ' . _webroot('/donations/'));
  }
  die();
}

function DoPost($action, &$user) {
  $user = new User();
  $user->Load($_SESSION['userId']);
  switch ($action) {
    case 'Add':
      // Only allow admins & donors to donate
      if ($user->HasRole(array('administrator', 'donator'))) {
        $donation = new Donation();
        $donation->Create($_SESSION['userId']);
        UpdateDonation($donation, $action);
      }
      header('location: ' . _webroot('/donations/'));
      die();
      break;

    case 'Update':
      // Only allow admins to change stuff
      if ($user->HasRole('administrator')) {
        $donation = new Donation();
        $donation->Load($_POST['DonationId']);
        UpdateDonation($donation, $action);
      }
      header('location: ' . _webroot('/donations/'));
      die();
      break;

    case 'Delete':
      $id = $_POST['DonationId'];
      $donation = new Donation();
      $donation->Load($id);
      if ($donation->User->UserId == $_SESSION['userId'] || $user->HasRole('administrator'))
        Donation::Delete($id);
      header('location: ' . _webroot('/donations/'));
      die();
      break;

    default:
      break;
  }
}

function DoAjax($action, &$user) {
  switch ($action) {
    case 'GetDonation':
      $id = $_POST['DonationId'];
      $donation = new Donation();
      if (!$donation->Load($id))
        die('[]');
      else {
        unset($donation->User->_PasswordHash);
        $donation->DateDonated = date('m/d/y', $donation->DateDonated);
        die(json_encode($donation));
      }
      break;

    case 'GetDonatedItem':
      $id = $_POST['DonatedItemId'];
      $donatedItem = new DonatedItem();
      if (!$donatedItem->Load($id))
        die('[]');
      else {
        $donatedItem->LastDateReceived = ($donatedItem->LastDateReceived ? date('m/d/Y', $donatedItem->LastDateReceived) : 'Never');
        die(json_encode($donatedItem));
      }
      break;

    case 'SubmitDonatedItem':
      $data = array();
      $item = new Item();
      $data['Success'] = true;
      $data['DonatedItemId'] = $_POST['DonatedItemId'];
      $data['Name'] = trim($_POST['Name']);
      $data['QuantityPledged'] = $_POST['QuantityPledged'];
      if (($data['QuantityPledged'] / 1) . '' != $data['QuantityPledged'] . '' || $data['QuantityPledged'] <= 0) {
        $data['Success'] = false;
        $data['Title'] = 'Invalid Format';
        $data['Message'] = 'Quantity Pledged is not a valid integer. Please enter a whole number greater than 0.';
      }
      if ($user->HasRole('administrator')) {
        $data['QuantityReceived'] = $_POST['QuantityReceived'];
        if (($data['QuantityReceived'] / 1) . '' != $data['QuantityReceived'] . '' || $data['QuantityReceived'] < 0) {
          $data['Success'] = false;
          $data['Title'] = 'Invalid Format';
          $data['Message'] = 'Quantity Received is not a valid integer. Please enter a whole number greater than or equal to 0.';
        }
        elseif ($data['QuantityReceived'] > $data['QuantityPledged']) {
          $data['Success'] = false;
          $data['Title'] = 'Too Many Items';
          $data['Message'] = 'Quantity Received cannot be greated than Quantity Pledged.';
        }
      }
      $donatedItem = new DonatedItem();
      $donatedItem->Load($data['DonatedItemId']);

      if ($data['Success']) {
        // New donated item
        if (!$donatedItem->DonatedItemId) {
          $isLoaded = $item->Load(Item::GetItemIdByItemName($data['Name']));
          // If an existing unverified item or non-existing item, lose the item id
          if (!$isLoaded || $isLoaded && !$item->IsVerified())
            $data['ItemId'] = 0;
          // Otherwise, use the existing, verified item id
          else
            $data['ItemId'] = $item->ItemId;
        }

        // Existing donated item
        else {
          $item = $donatedItem->Item;
          if (strtolower($item->Name) == strtolower($data['Name']))
            $data['ItemId'] = $item->ItemId;
          else {
            $itemByName = new Item();
            // Item passed by name exists
            if ($itemByName->Load(Item::GetItemIdByItemName($data['Name']))) {
              if ($itemByName->IsVerified() && $item->IsVerified()) {
                $data['Name'] = $itemByName->Name;
                $data['ItemId'] = $itemByName->ItemId;
              }
              elseif ($itemByName->IsVerified() && !$item->IsVerified()) {
                $data['Name'] = $itemByName->Name;
                $data['ItemId'] = $itemByName->ItemId;
              }
              elseif (!$itemByName->IsVerified() && $item->IsVerified()) {
                $data['Name'] = $itemByName->Name;
                $data['ItemId'] = 0;
              }
              elseif (!$itemByName->IsVerified() && !$item->IsVerified()) {
                $data['Name'] = $itemByName->Name;
                $data['ItemId'] = $item->ItemId;
              }
            }
            // Item passed by name does not exist
            else {
              // Donated item is verified
              if ($item->IsVerified()) {
                $data['Name'] = $data['Name'];
                $data['ItemId'] = 0;
              }
              // Donated item is not verified
              else {
                $data['Name'] = $data['Name'];
                $data['ItemId'] = $item->ItemId;
              }
            }
          }
        }
        if (!$data['Name']) {
          $data['Success'] = false;
          $data['Title'] = 'Enter An Item';
          $data['Message'] = 'Please enter an item. To get suggested items, start typing.';
        }
      }
      die(json_encode($data));
      break;

    default:
      die('[]');
      break;
  }
}

/**
  * Updates a donation in the DB based on POST vars.
  *
  * @param Donation
  * @param string
  */
function UpdateDonation(&$donation, $action) {
  // Get a list of all donated item ids and their data in posted donation
  $postedIds = array();
  $postedData = array();
  $newData = array();
  $donatedItemIdStringLength = strlen('DonatedItemId_');
  foreach ($_POST as $key => $val)
    if (strlen($key) > $donatedItemIdStringLength && substr($key, 0, $donatedItemIdStringLength) == 'DonatedItemId_') {
      $i = substr($key, $donatedItemIdStringLength);
      $id = $_POST['DonatedItemId_' . $i];
      if ($id > 0 && !in_array($id, $postedIds)) {
        $postedIds[] = $id;
        $postedData[$id] = array(
          'ItemId' => $_POST['ItemId_' . $i],
          'Name' => $_POST['Name_' . $i],
          'QuantityPledged' => $_POST['QuantityPledged_' . $i],
          'QuantityReceived' => $_POST['QuantityReceived_' . $i]
        );
      }
      elseif ($id == '0') {
        $newData[] = array(
          'ItemId' => $_POST['ItemId_' . $i],
          'Name' => $_POST['Name_' . $i],
          'QuantityPledged' => $_POST['QuantityPledged_' . $i],
          'QuantityReceived' => $_POST['QuantityReceived_' . $i]
        );
      }
    }

  // Get a list of all donated item ids in saved donation
  $currentIds = $donation->GetDonatedItemIds();

  // Find out which ids in the saved donation
  // do not exist in the posted donation,
  // and then go ahead and remove them
  $deletedIds = array_diff($currentIds, $postedIds);
  sort($deletedIds);
  $j = 0;
  for ($i = 0; $i < count($donation->DonatedItems); $i++)
    if (in_array($donation->DonatedItems[$i]->DonatedItemId, $deletedIds)) {
      if ($i == 0)
        array_shift($donation->DonatedItems);
      elseif ($i == count($donation->DonatedItems) - 1)
        array_pop($donation->DonatedItems);
      else
        array_splice($donation->DonatedItems, $i, 1);
      $i--;
    }

  // Update all existing donated items
  $updateIds = array_intersect($postedIds, $currentIds);
  for ($i = 0; $i < count($donation->DonatedItems); $i++)
    if (in_array($donation->DonatedItems[$i]->DonatedItemId, $updateIds)) {
      $data = $postedData[$donation->DonatedItems[$i]->DonatedItemId];
      // If the item doesn't exist, prep it for creation upon saving the Donation
      if ($data['ItemId'] == 0) {
        $donation->DonatedItems[$i]->Item = new Item();
        $donation->DonatedItems[$i]->Item->Name = $data['Name'];
        $donation->DonatedItems[$i]->Item->Verified = 0;
      }
      // Otherwise, load it
      else {
        $donation->DonatedItems[$i]->Item->Load($data['ItemId']);
        $donation->DonatedItems[$i]->Item->Verified = 1;
      }
      $donation->DonatedItems[$i]->QuantityPledged = $data['QuantityPledged'];
      $donation->DonatedItems[$i]->QuantityReceived = $data['QuantityReceived'];
    }

  // Add any new donated items
  for ($i = 0; $i < count($newData); $i++) {
    $donatedItem = new DonatedItem();
    $data = $newData[$i];
    $di = new DonatedItem();
    // If the item doesn't exist, prep it for creation upon saving the Donation
    if ($data['ItemId'] == 0) {
      $di->Item->ItemId = 0;
      $di->Item->Name = $data['Name'];
    }
    // Otherwise, load it
    else
      $di->Item->Load($data['ItemId']);
    $di->QuantityPledged = $data['QuantityPledged'];
    $di->QuantityReceived = $data['QuantityReceived'];
    $donation->DonatedItems[] = $di;
  }

  for ($i = 0; $i < count($donation->DonatedItems); $i++)
    if ($donation->DonatedItems[$i]->DonationId == -1)
      $donation->DonatedItems[$i]->DonationId = 0;

  // Finally, save the donation to the database
  $donation->Save();
}

// Launches the page; without this, nothing happens.
require_once('_loader.php');